package com.baselibrary.utils;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.WebView;

import androidx.annotation.RequiresApi;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

/**
 * Created by dhl on 2016/9/1.
 */
public class NetworkUtil {

    private NetworkUtil() {

    }

    public static final int NETWORK_WIFI = 1;    // wifi network
    public static final int NETWORK_4G = 4;    // "4G" networks
    public static final int NETWORK_3G = 3;    // "3G" networks
    public static final int NETWORK_2G = 2;    // "2G" networks
    public static final int NETWORK_UNKNOWN = 5;    // unknown network
    public static final int NETWORK_NO = -1;   // no network

    private static final int NETWORK_TYPE_GSM = 16;
    private static final int NETWORK_TYPE_TD_SCDMA = 17;
    private static final int NETWORK_TYPE_IWLAN = 18;

    public static List<String> typeList = new ArrayList<>();

    static {
        typeList.add("打开网络设置界面");
        typeList.add("获取活动网络信息");
        typeList.add("判断网络是否可用");
        typeList.add("判断网络是否是4G");
        typeList.add("判断wifi是否连接状态");
        typeList.add("获取移动网络运营商名称");
        typeList.add("获取当前的网络类型");
        typeList.add("获取当前的网络类型(WIFI,2G,3G,4G)");


    }


    /**
     * 获取活动网络信息
     *
     * @param context 上下文
     * @return NetworkInfo
     */
    public static NetworkInfo getActiveNetworkInfo(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        return cm.getActiveNetworkInfo();
    }

    /**
     * 判断网络是否可用
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>}</p>
     *
     * @param context 上下文
     * @return {@code true}: 可用<br>{@code false}: 不可用
     */
    public static boolean isAvailable(Context context) {
        NetworkInfo info = getActiveNetworkInfo(context);
        return info != null && info.isAvailable();
    }

    /**
     * 判断网络是否连接
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>}</p>
     *
     * @param context 上下文
     * @return {@code true}: 是<br>{@code false}: 否
     */
    public static boolean isConnected(Context context) {
        NetworkInfo info = getActiveNetworkInfo(context);
        return info != null && info.isConnected();
    }

    /**
     * 判断网络是否是4G
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>}</p>
     *
     * @param context 上下文
     * @return {@code true}: 是<br>{@code false}: 不是
     */
    public static boolean is4G(Context context) {
        NetworkInfo info = getActiveNetworkInfo(context);
        return info != null && info.isAvailable() && info.getSubtype() == TelephonyManager.NETWORK_TYPE_LTE;
    }

    /**
     * 判断wifi是否连接状态
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>}</p>
     *
     * @param context 上下文
     * @return {@code true}: 连接<br>{@code false}: 未连接
     */
    public static boolean isWifiConnected(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        return cm != null && cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI;
    }

    /**
     * 获取移动网络运营商名称
     * <p>如中国联通、中国移动、中国电信</p>
     *
     * @param context 上下文
     * @return 移动网络运营商名称
     */
    public static String getNetworkOperatorName(Context context) {
        TelephonyManager tm = (TelephonyManager) context
                .getSystemService(Context.TELEPHONY_SERVICE);
        return tm != null ? tm.getNetworkOperatorName() : null;
    }

    /**
     * 获取移动终端类型
     *
     * @param context 上下文
     * @return 手机制式
     * <ul>
     * <li>{@link TelephonyManager#PHONE_TYPE_NONE } : 0 手机制式未知</li>
     * <li>{@link TelephonyManager#PHONE_TYPE_GSM  } : 1 手机制式为GSM，移动和联通</li>
     * <li>{@link TelephonyManager#PHONE_TYPE_CDMA } : 2 手机制式为CDMA，电信</li>
     * <li>{@link TelephonyManager#PHONE_TYPE_SIP  } : 3</li>
     * </ul>
     */
    public static int getPhoneType(Context context) {
        TelephonyManager tm = (TelephonyManager) context
                .getSystemService(Context.TELEPHONY_SERVICE);
        return tm != null ? tm.getPhoneType() : -1;
    }


    /**
     * 获取当前的网络类型(WIFI,2G,3G,4G)
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>}</p>
     *
     * @param context 上下文
     * @return 网络类型
     * <ul>
     * <li>{@link #NETWORK_WIFI   } = 1;</li>
     * <li>{@link #NETWORK_4G     } = 4;</li>
     * <li>{@link #NETWORK_3G     } = 3;</li>
     * <li>{@link #NETWORK_2G     } = 2;</li>
     * <li>{@link #NETWORK_UNKNOWN} = 5;</li>
     * <li>{@link #NETWORK_NO     } = -1;</li>
     * </ul>
     */
    public static int getNetWorkType(Context context) {
        int netType = NETWORK_NO;
        NetworkInfo info = getActiveNetworkInfo(context);
        if (info != null && info.isAvailable()) {

            if (info.getType() == ConnectivityManager.TYPE_WIFI) {
                netType = NETWORK_WIFI;
            } else if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
                switch (info.getSubtype()) {

                    case NETWORK_TYPE_GSM:
                    case TelephonyManager.NETWORK_TYPE_GPRS:
                    case TelephonyManager.NETWORK_TYPE_CDMA:
                    case TelephonyManager.NETWORK_TYPE_EDGE:
                    case TelephonyManager.NETWORK_TYPE_1xRTT:
                    case TelephonyManager.NETWORK_TYPE_IDEN:
                        netType = NETWORK_2G;
                        break;

                    case NETWORK_TYPE_TD_SCDMA:
                    case TelephonyManager.NETWORK_TYPE_EVDO_A:
                    case TelephonyManager.NETWORK_TYPE_UMTS:
                    case TelephonyManager.NETWORK_TYPE_EVDO_0:
                    case TelephonyManager.NETWORK_TYPE_HSDPA:
                    case TelephonyManager.NETWORK_TYPE_HSUPA:
                    case TelephonyManager.NETWORK_TYPE_HSPA:
                    case TelephonyManager.NETWORK_TYPE_EVDO_B:
                    case TelephonyManager.NETWORK_TYPE_EHRPD:
                    case TelephonyManager.NETWORK_TYPE_HSPAP:
                        netType = NETWORK_3G;
                        break;

                    case NETWORK_TYPE_IWLAN:
                    case TelephonyManager.NETWORK_TYPE_LTE:
                        netType = NETWORK_4G;
                        break;
                    default:

                        String subtypeName = info.getSubtypeName();
                        if (subtypeName.equalsIgnoreCase("TD-SCDMA")
                                || subtypeName.equalsIgnoreCase("WCDMA")
                                || subtypeName.equalsIgnoreCase("CDMA2000")) {
                            netType = NETWORK_3G;
                        } else {
                            netType = NETWORK_UNKNOWN;
                        }
                        break;
                }
            } else {
                netType = NETWORK_UNKNOWN;
            }
        }
        return netType;
    }

    /**
     * 获取当前的网络类型(WIFI,2G,3G,4G)
     * <p>依赖上面的方法</p>
     *
     * @param context 上下文
     * @return 网络类型名称
     * <ul>
     * <li>NETWORK_WIFI   </li>
     * <li>NETWORK_4G     </li>
     * <li>NETWORK_3G     </li>
     * <li>NETWORK_2G     </li>
     * <li>NETWORK_UNKNOWN</li>
     * <li>NETWORK_NO     </li>
     * </ul>
     */
    public static String getNetWorkTypeName(Context context) {
        switch (getNetWorkType(context)) {
            case NETWORK_WIFI:
                return "NETWORK_WIFI";
            case NETWORK_4G:
                return "NETWORK_4G";
            case NETWORK_3G:
                return "NETWORK_3G";
            case NETWORK_2G:
                return "NETWORK_2G";
            case NETWORK_NO:
                return "NETWORK_NO";
            default:
                return "NETWORK_UNKNOWN";
        }
    }

    private static final String TAG = "NetworkUtils";

    /**
     * Returns whether the network is available
     *
     * @param context Context
     * @return 网络是否可用
     * @see [类、类#方法、类#成员]
     */
    public static boolean isNetworkAvailable(Context context) {
        return getConnectedNetworkInfo(context) != null;
    }

    /**
     * 打开网络设置界面
     * <p>3.0以下打开设置界面</p>
     *
     * @param context 上下文
     */
    public static void openWirelessSettings(Context context) {
        if (Build.VERSION.SDK_INT > 10) {
            context.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS));
        } else {
            context.startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS));
        }
    }

    public static boolean isNetworkOnline() {

        ConnectivityManager connMgr = (ConnectivityManager) HKUtils.getApp().getSystemService(Context.CONNECTIVITY_SERVICE);
        // 大于 6.0 的设备,使用新的方法
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//            if (connMgr != null) {
//                return checkNetworkOnlineUpM(connMgr);
//            }
//        } else {
        if (connMgr != null) {
            return checkNetworkOnlineDownM();
        }
//        }
        return false;
    }

    private static boolean checkNetworkOnlineDownM() {
        Runtime runtime = Runtime.getRuntime();
        try {
            Process ipProcess = runtime.exec("ping -c 3 www.baidu.com");
            int exitValue = ipProcess.waitFor();
            Log.i("Avalible", "Process:" + exitValue);
            return (exitValue == 0);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        return false;
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    private static boolean checkNetworkOnlineUpM(ConnectivityManager connMgr) {
        NetworkCapabilities networkCapabilities = connMgr.getNetworkCapabilities(connMgr.getActiveNetwork());
        Log.i("Avalible", "NetworkCapalbilities:" + networkCapabilities.toString());
        return networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
    }

    /**
     * 获取网络类型
     *
     * @param context Context
     * @return 网络类型
     * @see [类、类#方法、类#成员]
     */
    public static int getNetworkType(Context context) {
        NetworkInfo networkInfo = getConnectedNetworkInfo(context);
        if (networkInfo != null) {
            return networkInfo.getType();
        }

        return -1;
    }

    public static NetworkInfo getConnectedNetworkInfo(Context context) {
        try {
            ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(
                    Context.CONNECTIVITY_SERVICE);
            if (connectivity == null) {
            } else {
                NetworkInfo info = connectivity.getActiveNetworkInfo();
                if (info != null) {
                    /*
                     * for (int i = 0; i < info.length; i++) { if
                     * (info[i].getState() == NetworkInfo.State.CONNECTED) {
                     * return info[i]; } }
                     */
                    return info;
                }
            }

        } catch (Exception e) {
        }
        return null;
    }


    /**
     * 判断当前手机是否有网络
     *
     * @param context
     * @return
     */
    public static boolean isPhoneHasInternet(Context context) {
        ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity != null) {

            NetworkInfo[] allNetworkInfo = connectivity.getAllNetworkInfo();
            for (NetworkInfo info : allNetworkInfo) {
                if (info.getState() == NetworkInfo.State.CONNECTED) {
                    return true;
                }
            }
        }
        return false;
    }


    /**
     * 判断网络是不是手机网络，非wifi
     *
     * @param context Context
     * @return boolean
     * @see [类、类#方法、类#成员]
     */
    public static boolean isMobileNetwork(Context context) {
        return (ConnectivityManager.TYPE_MOBILE == getNetworkType(context));
    }

    /**
     * 判断网络是不是wifi
     *
     * @param context Context
     * @return boolean
     * @see [类、类#方法、类#成员]
     */
    public static boolean isWifiNetwork(Context context) {
        return (ConnectivityManager.TYPE_WIFI == getNetworkType(context));
    }

    /**
     * 手机是否连接wifi网络
     *
     * @param context
     * @return
     */
    public static int isWifiConnect(Context context) {
        ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        boolean isWifiConn = networkInfo.isConnected();
        return isWifiConn ? 1 : 0;
    }

    private static final String WIFISSID_UNKNOW = "<unknown ssid>";


    /**
     * 获取wifi的ssid 修复ANDROID 9 以上版本获取不到的BUG
     *
     * @param context
     * @return
     */
    public static String getWifiSSID(Context context) {
        /*
         *  先通过 WifiInfo.getSSID() 来获取
         */
        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        WifiInfo info = wifiManager.getConnectionInfo();
        String wifiId = info != null ? info.getSSID() : null;
        String result = wifiId != null ? wifiId.trim() : null;
        if (!TextUtils.isEmpty(result)) {
            // 部分机型上获取的 ssid 可能会带有 引号
            if (result.charAt(0) == '"' && result.charAt(result.length() - 1) == '"') {
                result = result.substring(1, result.length() - 1);
            }
        }
        // 如果上面通过 WifiInfo.getSSID() 来获取到的是 空或者 <unknown ssid>，则使用 networkInfo.getExtraInfo 获取
        if (TextUtils.isEmpty(result) || WIFISSID_UNKNOW.equalsIgnoreCase(result.trim())) {
            NetworkInfo networkInfo = getNetworkInfo(context);
            if (networkInfo.isConnected()) {
                if (networkInfo.getExtraInfo() != null) {
                    result = networkInfo.getExtraInfo().replace("\"", "");
                }
            }
        }
        // 如果获取到的还是 空或者 <unknown ssid>，则遍历 wifi 列表来获取
        if (TextUtils.isEmpty(result) || WIFISSID_UNKNOW.equalsIgnoreCase(result.trim())) {
            result = getSSIDByNetworkId(context);
        }
        return result;

    }

    public static NetworkInfo getNetworkInfo(Context context) {
        try {
            final ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            if (null != connectivityManager) {
                return connectivityManager.getActiveNetworkInfo();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 遍历wifi列表来获取
     *
     * @param context
     * @return
     */
    private static String getSSIDByNetworkId(Context context) {
        String ssid = WIFISSID_UNKNOW;
        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        if (wifiManager != null) {
            WifiInfo wifiInfo = wifiManager.getConnectionInfo();
            int networkId = wifiInfo.getNetworkId();
            List<WifiConfiguration> configuredNetworks = wifiManager.getConfiguredNetworks();
            for (WifiConfiguration wifiConfiguration : configuredNetworks) {
                if (wifiConfiguration.networkId == networkId) {
                    ssid = wifiConfiguration.SSID;
                    break;
                }
            }
        }
        return ssid;
    }


    public static class ConnectionType {
        public static final int Unknown = 0;
        public static final int Ethernet = 1;
        public static final int Wifi = 2;
        public static final int Unknown_Generation = 3;
        public static final int G2 = 4;
        public static final int G3 = 5;
        public static final int G4 = 6;

    }

    public static String getConnectionType(Context context, int t) {
        int type = getConnectionType(context);
        String netType = "";
        switch (type) {
            case ConnectionType.Unknown:
                netType = "unknown";
                break;

            case ConnectionType.Ethernet:
                netType = "ethernet";
                break;

            case ConnectionType.Wifi:
                netType = "wifi";
                break;

            case ConnectionType.Unknown_Generation:
                netType = "unknown_generation";
                break;

            case ConnectionType.G2:

                netType = "2G";
                break;

            case ConnectionType.G3:

                netType = "3G";
                break;
            case ConnectionType.G4:

                netType = "4G";
                break;

            default:

//                netType = "unknown";
//                break;

        }

        return netType;
    }

    public static int getConnectionType(Context context) {

        if (isWifiNetwork(context)) {
            return ConnectionType.Wifi;
        } else {
            NetworkInfo networkInfo = getConnectedNetworkInfo(context);
            if (networkInfo == null) {
                return ConnectionType.Unknown;
            }
            int nType = networkInfo.getType();
            if (nType != ConnectivityManager.TYPE_MOBILE) {
                return ConnectionType.Unknown;
            }
            try {
                final Cursor c = context.getContentResolver().query(PREFERRED_APN_URI, null, null, null, null);
                if (c != null) {
                    c.moveToFirst();
                    final String user = c.getString(c.getColumnIndex("user"));
                    if (!TextUtils.isEmpty(user)) {
                        if (user.startsWith(CTWAP)) {
                            return ConnectionType.G2;
                        }
                    }
                }
                c.close();
            } catch (Exception e) {
            }
            String extraInfo = networkInfo.getExtraInfo();
            HKLogUtils.d(TAG, "extraInfo:" + extraInfo);
            if (extraInfo != null) {
                // 通过apn名称判断是否是联通和移动wap
                extraInfo = extraInfo.toLowerCase();
                if (extraInfo.equals(CMWAP) || extraInfo.equals(WAP_3G) || extraInfo.equals(UNIWAP)) {
                    HKLogUtils.d(TAG, " ======>移动联通wap网络");
                    return ConnectionType.G2;
                }
            }

            HKLogUtils.d(TAG, " ======>net网络");

            return ConnectionType.G3;
        }

    }

    public static final String CTWAP = "ctwap";

    public static final String CMWAP = "cmwap";

    public static final String WAP_3G = "3gwap";

    public static final String UNIWAP = "uniwap";

    public static final int APN_TYPE_DISABLED = -1;// 网络不可用

    public static final int APN_TYPE_OTHER = 0;

    public static final int APN_TYPE_CM_CU_WAP = 1;// 移动联通wap10.0.0.172

    public static final int APN_TYPE_CT_WAP = 2;// 电信wap 10.0.0.200

    public static final int APN_TYPE_NET = 3;// 电信,移动,联通,wifi 等net网络

    public static Uri PREFERRED_APN_URI = Uri.parse("content://telephony/carriers/preferapn");

    /**
     * 获取接入点类型</br>
     * Net网络：运营商（移动联通电信）net网络，wifi，usb网络共享<br/>
     * Wap网络：移动联通wap（代理相同：10.0.0.172：80），电信wap（代理：10.0.0.200：80）<br/>
     */
    public static int getAPNType(Context context) {

        NetworkInfo networkInfo = getConnectedNetworkInfo(context);
        if (networkInfo == null) {
            return APN_TYPE_DISABLED;
        }

        int nType = networkInfo.getType();
        if (nType != ConnectivityManager.TYPE_MOBILE) {
            return APN_TYPE_OTHER;
        }

        // 判断是否电信wap:
        // 不要通过getExtraInfo获取接入点名称来判断类型，
        // 因为通过目前电信多种机型测试发现接入点名称大都为#777或者null，
        // 电信机器wap接入点中要比移动联通wap接入点多设置一个用户名和密码,
        // 所以可以通过这个进行判断！
        try {
            final Cursor c = context.getContentResolver().query(PREFERRED_APN_URI, null, null, null, null);
            if (c != null) {
                c.moveToFirst();
                final String user = c.getString(c.getColumnIndex("user"));
                if (!TextUtils.isEmpty(user)) {
                    HKLogUtils.d(TAG, "===>代理：" + c.getString(c.getColumnIndex("proxy")));
                    if (user.startsWith(CTWAP)) {
                        HKLogUtils.d(TAG, "===>电信wap网络");
                        return APN_TYPE_CT_WAP;
                    }
                }
            }
            c.close();
        } catch (Exception e) {
            HKLogUtils.e(TAG, e.toString());
        }

        // 判断是移动联通wap:
        // 其实还有一种方法通过getString(c.getColumnIndex("proxy")获取代理ip
        // 来判断接入点，10.0.0.172就是移动联通wap，10.0.0.200就是电信wap，但在
        // 实际开发中并不是所有机器都能获取到接入点代理信息，例如魅族M9 （2.2）等...
        // 所以采用getExtraInfo获取接入点名字进行判断
        String extraInfo = networkInfo.getExtraInfo();
        HKLogUtils.d(TAG, "extraInfo:" + extraInfo);
        if (extraInfo != null) {
            // 通过apn名称判断是否是联通和移动wap
            extraInfo = extraInfo.toLowerCase();
            if (extraInfo.equals(CMWAP) || extraInfo.equals(WAP_3G) || extraInfo.equals(UNIWAP)) {
                HKLogUtils.d(TAG, " ======>移动联通wap网络");
                return APN_TYPE_CM_CU_WAP;
            }
        }

        HKLogUtils.d(TAG, " ======>net网络");

        return APN_TYPE_NET;

    }

    /**
     * 3GWAP,uniwap 下不取号
     */
    public static boolean is3GWAP(Context context) {
        try {
            NetworkInfo networkInfo = getConnectedNetworkInfo(context);
            if (networkInfo != null) {
                String extraInfo = networkInfo.getExtraInfo();
                if (extraInfo != null && (WAP_3G.equalsIgnoreCase(extraInfo) || UNIWAP.equalsIgnoreCase(extraInfo))) {
                    return true;
                }
            }
        } catch (Exception e) {
            HKLogUtils.e(TAG, "CHECK 3GWAP ERROR");
        }
        return false;
    }

    /**
     * 获取wifi名称 android 9 获取不到
     */
   /* public static String getWifiSSID(Context context) {
        if (isWifiNetwork(context)) {
            try {
                WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
                WifiInfo info = wifi.getConnectionInfo();
                return info.getSSID();
            } catch (Exception e) {
                LogUtils.e(TAG, e.toString());
            }
        }
        return null;
    }*/

    /**
     * Returns whether the network is roaming
     *
     * @param context Context
     * @return boolean
     * @see [类、类#方法、类#成员]
     */
    public static boolean isNetworkRoaming(Context context) {
        try {
            ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(
                    Context.CONNECTIVITY_SERVICE);
            if (connectivity == null) {
                HKLogUtils.e(TAG, "couldn't get connectivity manager");
            } else {
                NetworkInfo info = connectivity.getActiveNetworkInfo();
                TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(
                        Context.TELEPHONY_SERVICE);
                if (info != null && info.getType() == ConnectivityManager.TYPE_MOBILE) {
                    if (/* TelephonyManager.getDefault() */telephonyManager.isNetworkRoaming()) {

                        return true;
                    } else {

                    }
                } else {

                }
            }

        } catch (Exception e) {
            HKLogUtils.e(TAG, e.toString());
        }

        return false;
    }

    /**
     * 获取本机ip。
     */
    public static String getLocalIpAddress() {
        // String ipaddress = "";
        try {
            Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
            while (en.hasMoreElements()) {
                NetworkInterface intf = en.nextElement();
                Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses();
                while (enumIpAddr.hasMoreElements()) {
                    InetAddress inetAddress = enumIpAddr.nextElement();

                    // loopback地址就是代表本机的IP地址，只要第一个字节是127，就是lookback地址
                    if (!inetAddress.isLoopbackAddress() && !inetAddress.isLinkLocalAddress()) {
                        return inetAddress.getHostAddress();
                        // ipaddress = ipaddress + ";" +
                        // inetAddress.getHostAddress().toString();
                    }
                }
            }
        } catch (Exception e) {
            HKLogUtils.e(TAG, e.toString());
        }
        return null;
        // return ipaddress;
    }

    /**
     * 手机号码
     */
//    public static String getLine1Number(Context context) {
//        try {
//            TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
//            return telephonyManager.getLine1Number();
//        } catch (Exception e) {
//            HKLogUtils.e(TAG, e.toString());
//        }
//        return "";
//    }

    /**
     * 判断端口是否被占用
     */
    public static boolean isPortUsed(int port) {
        String[] cmds = {"netstat", "-an"};
        Process process = null;
        InputStream is = null;
        DataInputStream dis = null;
        try {

            String line = "";
            Runtime runtime = Runtime.getRuntime();

            process = runtime.exec(cmds);
            is = process.getInputStream();
            dis = new DataInputStream(is);
            while ((line = dis.readLine()) != null) {
                // LogUtils.error(line);
                if (line.contains(":" + port)) {
                    return true;
                }
            }
        } catch (Exception e) {
            HKLogUtils.e(TAG, e.toString());
        } finally {
            try {
                if (dis != null) {
                    dis.close();
                }
                if (is != null) {
                    is.close();
                }
                if (process != null) {
                    process.destroy();
                }
            } catch (Exception e) {
                HKLogUtils.e(TAG, e.toString());
            }
        }
        return false;
    }

    public static String getMacAddressPure(Context context) {
        String addr = getMacAddress(context);
        if (addr == null) {
            return "";
        }
        String addrNoColon = addr.replaceAll(":", "");
        String addrNoLine = addrNoColon.replaceAll("-", "");

        return addrNoLine.toUpperCase();

    }

    private static String getWifiMacAddress(Context context) {
        try {
            WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            WifiInfo info = wifi.getConnectionInfo();
            return info.getMacAddress();
        } catch (Exception e) {
            HKLogUtils.e(TAG, e.toString());
        }
        return "";
    }

    public static String getMacAddress(Context context) {
        String addr = getMacAddrInFile("/sys/class/net/eth0/address");
        if (TextUtils.isEmpty(addr)) {
            addr = getMacAddrInFile("/sys/class/net/wlan0/address");
        }

        if (TextUtils.isEmpty(addr)) {
            return getWifiMacAddress(context);
        }

        return addr;
    }

    private static String getMacAddrInFile(String filepath) {
        File f = new File(filepath);
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(f);
            BufferedReader rd = new BufferedReader(new InputStreamReader(fis));
            String str = rd.readLine();

            // 去除空格
            str = str.replaceAll(" ", "");

            // 查看是否是全0的无效MAC地址 如 00:00:00:00:00:00
            String p = str.replaceAll("-", "");
            p = p.replaceAll(":", "");
            if (p.matches("0*")) {
                return null;
            }
            return str;
        } catch (Exception e) {
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                }
            }
        }
        return null;
    }

    /**
     * Convert byte array to hex string
     *
     * @param bytes
     * @return
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuilder sbuf = new StringBuilder();
        for (int idx = 0; idx < bytes.length; idx++) {
            int intVal = bytes[idx] & 0xff;
            if (intVal < 0x10)
                sbuf.append("0");
            sbuf.append(Integer.toHexString(intVal).toUpperCase());
        }
        return sbuf.toString();
    }

    /**
     * Get utf8 byte array.
     *
     * @param str
     * @return array of NULL if error was found
     */
    public static byte[] getUTF8Bytes(String str) {
        try {
            return str.getBytes(StandardCharsets.UTF_8);
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     * Load UTF8withBOM or any ansi text file.
     *
     * @param filename
     * @return
     * @throws IOException
     */
    public static String loadFileAsString(String filename) throws IOException {
        final int BUFLEN = 1024;
        BufferedInputStream is = new BufferedInputStream(new FileInputStream(filename), BUFLEN);
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream(BUFLEN);
            byte[] bytes = new byte[BUFLEN];
            boolean isUTF8 = false;
            int read, count = 0;
            while ((read = is.read(bytes)) != -1) {
                if (count == 0 && bytes[0] == (byte) 0xEF && bytes[1] == (byte) 0xBB && bytes[2] == (byte) 0xBF) {
                    isUTF8 = true;
                    baos.write(bytes, 3, read - 3); // drop UTF8 bom marker
                } else {
                    baos.write(bytes, 0, read);
                }
                count += read;
            }
            return isUTF8 ? new String(baos.toByteArray(), StandardCharsets.UTF_8) : new String(baos.toByteArray());
        } finally {
            try {
                is.close();
            } catch (Exception ex) {
            }
        }
    }

    /**
     * Returns MAC address of the given interface name.
     *
     * @param interfaceName eth0, wlan0 or NULL=use first interface
     * @return mac address or empty string
     */
    public static String getMACAddress(String interfaceName) {
        try {
            List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface intf : interfaces) {
                if (interfaceName != null) {
                    if (!intf.getName().equalsIgnoreCase(interfaceName))
                        continue;
                }
                byte[] mac = intf.getHardwareAddress();
                if (mac == null)
                    return "";
                StringBuilder buf = new StringBuilder();
                for (int idx = 0; idx < mac.length; idx++)
                    buf.append(String.format("%02X:", mac[idx]));
                if (buf.length() > 0)
                    buf.deleteCharAt(buf.length() - 1);
                return buf.toString();
            }
        } catch (Exception ex) {
        } // for now eat exceptions
        return "";
        /*
         * try { // this is so Linux hack return
         * loadFileAsString("/sys/class/net/" +interfaceName +
         * "/address").toUpperCase().trim(); } catch (IOException ex) { return
         * null; }
         */
    }

//    /**
//     * Get IP address from first non-localhost interface
//     *
//     * @param ipv4 true=return ipv4, false=return ipv6
//     * @return address or empty string
//     */
//    public static String getIPAddress(boolean useIPv4)
//    {
//        try
//        {
//            List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
//            for (NetworkInterface intf : interfaces)
//            {
//                List<InetAddress> addrs = Collections.list(intf.getInetAddresses());
//                for (InetAddress addr : addrs)
//                {
//                    if (!addr.isLoopbackAddress())
//                    {
//                        String sAddr = addr.getHostAddress().toUpperCase();
//                        boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr);
//                        if (useIPv4)
//                        {
//                            if (isIPv4)
//                                return sAddr;
//                        }
//                        else
//                        {
//                            if (!isIPv4)
//                            {
//                                int delim = sAddr.indexOf('%'); // drop ip6
//                                                                // port suffix
//                                return delim < 0 ? sAddr : sAddr.substring(0, delim);
//                            }
//                        }
//                    }
//                }
//            }
//        }
//        catch (Exception ex)
//        {
//        } // for now eat exceptions
//        return "";
//    }

    /**
     * @author youxueliu
     */
    public static class NetworkReceiverUtil {

        public static void registNetworkReceive(Context context, BroadcastReceiver networkReceiver) {
            if (context == null || networkReceiver == null)
                return;
            try {
                IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
                context.registerReceiver(networkReceiver, intentFilter);
            } catch (IllegalArgumentException e) {
                HKLogUtils.e(TAG, " e.getMessage:" + e.getMessage());
            }
        }

        public static void unregisterNetworkReceive(Context context, BroadcastReceiver networkReceiver) {
            if (context == null || networkReceiver == null)
                return;
            try {
                if (networkReceiver != null)
                    context.unregisterReceiver(networkReceiver);
            } catch (Exception e) {
                HKLogUtils.e(TAG, "unregister error: " + e);
            }
        }

    }

    public static void initUserAgent(Context c) {
        String ua = null;
        try {
            WebView mes = new WebView(c);
            ua = mes.getSettings().getUserAgentString();
        } catch (Throwable e) {
            HKLogUtils.e(TAG, "init agent error:" + e);
        }
        if (!TextUtils.isEmpty(ua)) {
            USER_AGENT = ua;
        } else {

            try {
                ua = System.getProperty("http.agent");
            } catch (Throwable e) {
                HKLogUtils.e(TAG, "init agent error2:" + e);
            }

            if (!TextUtils.isEmpty(ua)) {
                USER_AGENT = ua;
            }
        }
        HKLogUtils.e(TAG, "UA:" + USER_AGENT);
    }

    public static String USER_AGENT = "Mozilla/5.0 (Linux; U; Android " + Build.VERSION.RELEASE + "; Build/" + Build.ID
            + ")";

}